package com.xteam.xnetworkdisk.sys.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xteam.xnetworkdisk.common.CurrentUser;
import com.xteam.xnetworkdisk.constant.Constant;
import com.xteam.xnetworkdisk.dto.UserLoginDTO;
import com.xteam.xnetworkdisk.sys.dao.FileDao;
import com.xteam.xnetworkdisk.sys.dao.SettingsDao;
import com.xteam.xnetworkdisk.sys.entity.Category;
import com.xteam.xnetworkdisk.sys.entity.FileEntity;
import com.xteam.xnetworkdisk.sys.entity.SettingsEntity;
import com.xteam.xnetworkdisk.utils.*;
import com.xteam.xnetworkdisk.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutorService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.xteam.xnetworkdisk.sys.dao.UserDao;
import com.xteam.xnetworkdisk.sys.entity.UserEntity;
import com.xteam.xnetworkdisk.sys.service.UserService;
import org.springframework.web.multipart.MultipartFile;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Slf4j
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
    @Autowired
    private UserDao userDao;

//    @Autowired
//    private MinioUtilsNew minioUtils;

    @Autowired
    private SettingsDao settingsDao;

    @Autowired
    private IPService ipService;

    @Autowired
    private FileDao fileDao;

    @Autowired
    private FileLocalUtils fileLocalUtils;

    @Autowired
    private JavaMailSender javaMailSender;
    @Value("${spring.mail.username}")
    private String mailUsername;

    @Autowired
    private ProjectInfoAutoConfiguration projectInfoAutoConfiguration;
    @Autowired
    private DataSourceTransactionManagerAutoConfiguration dataSourceTransactionManagerAutoConfiguration;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params),
                new QueryWrapper<UserEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public R updateAvatar(int userId, MultipartFile avatarFile) {
        UserEntity userEntity = userDao.selectById(userId);
        if(userEntity == null) {
            return R.error(404,"未找到用户");
        }
        if (avatarFile.isEmpty()) {
            return R.error(400, "文件为空");
        }

        try {
            String originalFilename = avatarFile.getOriginalFilename();
            String suffix = Tools.getSuffix(originalFilename);

            String path = fileLocalUtils.uploadFile(avatarFile, Constant.USER_AVATAR_BUKET,suffix);

            if(path == null){
                return R.error(400,"文件上传失败");
            }

            String fullPath = Constant.FILE_LOCAL_PATH + "/" + Constant.USER_FILE_BUKET + "Avatar/preview/" + path;

            // 更新用户头像URL
            String uAvatar = userEntity.getAvatar();
            userEntity.setAvatar(fullPath);

            userDao.updateById(userEntity);

            if (uAvatar != null) {
                fileLocalUtils.deleteFile(uAvatar);
            }

            return R.ok("头像更新成功");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public R getAvatar(Integer userId) {
        UserEntity userEntity = userDao.selectById(userId);
        if(userEntity == null) {
            return R.error(404,"未找到用户");
        }
        String url = userEntity.getAvatar();
        HashMap<String, Object> stringStringMap = new HashMap<>();
        stringStringMap.put("url",url);
        return R.ok(stringStringMap);
    }



    @Override
    public R register(UserRegisterSendEmailVO registerSendEmailVO) {
        String username = registerSendEmailVO.getUsername();
        String password = registerSendEmailVO.getPassword();
        String cpassword = registerSendEmailVO.getCpassword();

        if (!password.equals(cpassword)) {
            return R.error("密码不匹配");
        }

        Boolean qqEmail = Tools.isQQEmail(username);
        Boolean neteaseEmail = Tools.isNeteaseEmail(username);
        if(!qqEmail&&!neteaseEmail){
            return R.error("账号输入格式有误，请重新输入");
        }

        UserEntity userregister=new UserEntity();
        userregister.setUsername(username);
        userregister.setPassword(password);

        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        UserEntity user = userDao.selectOne(wrapper);

        if(Objects.nonNull(user) && user.getIsValid().equals(UserEntity.VALID)){
            return R.error("此账户以注册");
        } else{
            userDao.deleteById(user);
        }

        Boolean account = createAccount(userregister,UserEntity.INVALID, Category.USER,username);
        if(!account){
            return R.error("创建账户失败");
        }

        ExecutorService executorService = ThreadPoolManager.getExecutorService();
        executorService.execute(()->{
            Boolean aBoolean = sendEmail(userregister);
        });

        return R.ok("email已发送，请及时查收");
    }



    @Override
    public R verification(UserRegisterVerificationVO userRegisterVerification, HttpServletRequest request) {
        String cpassword = userRegisterVerification.getCpassword();
        String verificationCode = userRegisterVerification.getVerificationCode();
        String username = userRegisterVerification.getUsername();
        String name = userRegisterVerification.getName();
        String password = userRegisterVerification.getPassword();

        String[] locationByRequest = ipService.getLocationByRequest(request);
        String location = locationByRequest[1];
        String ip = locationByRequest[0];
        log.info("location:{}",location);

        if (!password.equals(cpassword)) {
            return R.error("密码不匹配");
        }

        Boolean qqEmail = Tools.isQQEmail(username);
        Boolean neteaseEmail = Tools.isNeteaseEmail(username);
        if (!qqEmail&&!neteaseEmail) {
            return R.error("账号格式错误");
        }

        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        UserEntity user = userDao.selectOne(wrapper);

        if (Objects.isNull(user)) {
            return R.error("请先获取验证码");
        }

        if(user.getIsValid().equals(UserEntity.VALID)){
            return R.error("该用户已激活");

        }

        if(!user.getVerifyCode().equals(verificationCode)){
            return R.error("验证码不正确");
        }

        user.setIsValid(UserEntity.VALID);
        user.setCity(location);
        user.setName(name);
        int i = userDao.updateById(user);
        if(i==0){
            return R.error("激活失败");
        }

        //为用户创建出目录
        FileEntity fileEntity = new FileEntity();
        fileEntity.setUserId(user.getUId());
        fileEntity.setIsFolder(true);
        fileEntity.setFileName(user.getUsername());
        fileEntity.setCreatedAt(new Date());
        fileEntity.setUpdatedAt(new Date());
        fileEntity.setIsValid(true);
        fileDao.insertFile(fileEntity);

        //为用户创建settings
        SettingsEntity settings = new SettingsEntity();
        settings.setUserId(user.getUId());
        settings.setEmail(user.getUsername());
        settings.setLoginIp(ip);
        settings.setDarkMode(Constant.DARK_MODE_LIGHT);
        settings.setLoginAdress(location);
        settings.setSyncMode(Constant.SYNC_MODE_SYNC);
        settings.setAbnormalEmailAlert(Constant.ABNORMAL_EMAIL_ALERT_ON);
        settingsDao.insertSettings(settings);

        return R.ok("成功激活用户");
    }


    @Override
    public Map<String, Object> login(UserLoginVO userLoginVO, HttpSession session) {

        Map<String, Object> resultMap = new HashMap<>();

        String password = userLoginVO.getPassword();
        String username = userLoginVO.getUsername();

        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        UserEntity user = userDao.selectOne(wrapper);
        Integer userId = user.getUId(); // 假设用户ID类型是Long
        resultMap.put("userId", userId);

        UserLoginDTO userLoginDTO = new UserLoginDTO();
        userLoginDTO.setAge(user.getAge());
        userLoginDTO.setSex(user.getSex());
        userLoginDTO.setName(user.getName());
        userLoginDTO.setPhone(user.getPhone());
        userLoginDTO.setUsername(user.getUsername());
        userLoginDTO.setRoleId(user.getRoleId());
        userLoginDTO.setCity(user.getCity());


        if(Objects.isNull(user)){
            resultMap.put("result", R.error("未找到该用户").put("userInfo", userLoginDTO));
            return resultMap;
        }

        if(user.getIsValid().equals(UserEntity.INVALID)){
            resultMap.put("result", R.error("该账户未激活，请重新激活该账户").put("userInfo", userLoginDTO));
            return resultMap;
        }

        String pswd = SecureUtil.md5(password + user.getSalt());

        if(!pswd.equals(user.getPassword())){
            resultMap.put("result", R.error("密码错误").put("userInfo", userLoginDTO));
            return resultMap;
        }

        resultMap.put("result", R.ok().put("userInfo", userLoginDTO));
        return resultMap;
    }



    @Override
    public R resetPasswordSendeMail(String username) {
        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        UserEntity user = userDao.selectOne(wrapper);

        if(Objects.isNull(user)){
            return R.error("未找到该用户");
        }
        if(user.getIsValid().equals(UserEntity.INVALID)){
            return R.error("该账户未激活");
        }
        ExecutorService executorService = ThreadPoolManager.getExecutorService();

        executorService.execute(()->{
            Boolean aBoolean = sendEmail(user);
        });

        return R.ok("发送邮件成功，请及时查收");
    }


    @Override
    public R resetPasswordVerify(UserResetPasswordVertifyVO userResetPasswordVertifyVO) {
        String verificationCode = userResetPasswordVertifyVO.getVerificationCode();
        String username = userResetPasswordVertifyVO.getUsername();
        String password = userResetPasswordVertifyVO.getPassword();

        if(Objects.isNull(password)){
            return R.error("密码不能为空");
        }

        QueryWrapper<UserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("username",username);
        UserEntity user = userDao.selectOne(wrapper);

        if(Objects.isNull(user)){
            return R.error("未找到该用户");
        }

        if(user.getIsValid().equals(UserEntity.INVALID)){
            return R.error("该账户未激活");
        }

        if(!user.getVerifyCode().equals(verificationCode)){
            return R.error("验证码不正确");
        }

        String pswd = SecureUtil.md5(password + user.getSalt());
        user.setPassword(pswd);
        userDao.updateById(user);
        return R.ok("密码重置成功");
    }



    @Override
    public R modify(UserModifyVO userModifyVO) {
        Integer age = userModifyVO.getAge();
        Integer sex = userModifyVO.getSex();
        String phone = userModifyVO.getPhone();
        String name = userModifyVO.getName();
        Integer uId = CurrentUser.getCurrentUserId();
        System.out.println(uId);

        UserEntity user = userDao.selectById(uId);

        if(Objects.isNull(user)){
            return R.error("未找到该用户");
        }

        if(Objects.nonNull(name)){
            user.setName(name);
        }
        if(Objects.nonNull(sex)){
            user.setSex(sex);
        }
        if(Objects.nonNull(age)){
            user.setAge(age);
        }
        if(Objects.nonNull(phone)){
            user.setPhone(phone);
        }

        int i = userDao.updateById(user);
        if(i==0){
            return R.error("更新失败");
        }else{
            return R.ok("更新成功");
        }
    }


    @Override
    public R listPage(UserListPageVO userListPageVO) {
        int pageNumber = userListPageVO.getPageNumber();
        int pageSize = userListPageVO.getPageSize();
        String sex = userListPageVO.getSex();
        List<Integer> categories = userListPageVO.getCategories();
        String name = userListPageVO.getName();

        // 创建Page对象
        Page<UserEntity> page = new Page<>(pageNumber, pageSize);

        // 创建LambdaQueryWrapper
        LambdaQueryWrapper<UserEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        // 处理categories查询条件
        if (!categories.equals("") && categories != null && !categories.isEmpty()) {
            lambdaQueryWrapper.and(wrapper -> {
                for (Integer category : categories) {
                    wrapper.or(i -> i.like(UserEntity::getRoleId, category));
                }
            });
        }

        // 处理name查询条件
        if (Objects.nonNull(name) && !name.trim().isEmpty()) {
            lambdaQueryWrapper.like(UserEntity::getName, name);
        }

        // 处理sex查询条件
        if (Objects.nonNull(sex) && !sex.trim().isEmpty()) {
            Integer gender = Integer.parseInt(sex);
            lambdaQueryWrapper.eq(UserEntity::getSex, gender);
        }

        // 使用mybatisplus获取符合模糊查询后的且分页的列表
        Page<UserEntity> page1 = userDao.selectPage(page, lambdaQueryWrapper);

        return R.ok().put("page",page1);
    }


    public Boolean createAccount(UserEntity user,String isvalid,Integer roleid,String name){
        String s = IdUtil.getSnowflake(1, 1).nextIdStr();
        String s1 = RandomUtil.randomString(6);
        String s2 = SecureUtil.md5(user.getPassword() + s1);
        user.setName(name);
        int startIndex = s.length() - 6;
        user.setVerifyCode(s.substring(startIndex));
        user.setSalt(s1);
        user.setPassword(s2);
        user.setIsValid(isvalid);
        user.setTotalSpace(Constant.USER_DEFAULT_SPACE);
        user.setUseSpace(0L);
        int insert = userDao.insertUser(user);
        return insert==0?false:true;
    }

    public Boolean sendEmail(UserEntity user) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); // 设为true以支持HTML内容
            mimeMessageHelper.setFrom(mailUsername);
            mimeMessageHelper.setTo(user.getUsername());
            mimeMessageHelper.setSubject("欢迎使用骁合云盘");

            // 读取 HTML 文件内容并指定编码为 UTF-8
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("static/register.html");
            String htmlTemplate = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);


            // 替换占位符内容
            String htmlContent = htmlTemplate.replace("{{username}}", user.getUsername())
                    .replace("{{verificationCode}}", user.getVerifyCode());

            // 设置邮件内容为HTML格式
            mimeMessageHelper.setText(htmlContent, true);

            javaMailSender.send(mimeMessage);
            return true;
        } catch (MessagingException | IOException e) {
            e.printStackTrace(); // 打印堆栈跟踪以便调试
            return false;
        }
    }
    @Override
    public Boolean loginFromANewLocationSendEmail(String email,String newLocation,String name) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); // 设为true以支持HTML内容
            mimeMessageHelper.setFrom(mailUsername);
            mimeMessageHelper.setTo(email);
            mimeMessageHelper.setSubject("异地登录提醒");

            // 读取 HTML 文件内容并指定编码为 UTF-8
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("static/login_alert.html");
            String htmlTemplate = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);


            // 替换占位符内容
            String htmlContent = htmlTemplate
                    .replace("{{name}}", name)
                    .replace("{{username}}", email)
                    .replace("{{newLocation}}", newLocation)
                    .replace("{{date}}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")));

            // 设置邮件内容为HTML格式
            mimeMessageHelper.setText(htmlContent, true);

            javaMailSender.send(mimeMessage);
            return true;
        } catch (MessagingException | IOException e) {
            e.printStackTrace(); // 打印堆栈跟踪以便调试
            return false;
        }
    }

    @Override
    public R changeEmail(ChangeEmailVO changeEmailVO) {
        String email = changeEmailVO.getEmail();
        String verificationCode = changeEmailVO.getVerificationCode();

        Integer currentUserId = CurrentUser.getCurrentUserId();
        UserEntity userEntity = userDao.selectById(currentUserId);

        if (!userEntity.getVerifyCode().equals(verificationCode)){
            return R.error("验证码错误");
        }

        if (userEntity == null){
            return R.error("出错了，请联系管理员");
        }
        userEntity.setUsername(email);
        int i = userDao.updateById(userEntity);
        if(i == 0){
            return R.error("修改失败");
        }
        return R.ok();
    }

    @Override
    public R sendEmailResetE(String email) {
        Integer currentUserId = CurrentUser.getCurrentUserId();
        UserEntity userEntity = userDao.selectById(currentUserId);
        userEntity.setUsername(email);

        if(userEntity == null){
            return R.error("未找到对应用户");
        }

        ExecutorService executorService = ThreadPoolManager.getExecutorService();

        executorService.execute(()->{
            Boolean aBoolean = sendEmail(userEntity);
        });

        return R.ok("发送邮件成功，请及时查收");
    }

    @Override
    public R updateBackground(Integer userId, MultipartFile background) {

        UserEntity userEntity = userDao.selectById(userId);
        if(userEntity == null) {
            return R.error(404,"未找到用户");
        }
        if (background.isEmpty()) {
            return R.error(400, "文件为空");
        }

        try {
            String originalFilename = background.getOriginalFilename();
            String suffix = Tools.getSuffix(originalFilename);

            String path = fileLocalUtils.uploadFile(background, Constant.USER_BACKGROUND_BUKET,suffix);

            if(path == null){
                return R.error(400,"文件上传失败");
            }

            String fullPath = Constant.FILE_LOCAL_PATH + "/" + Constant.USER_FILE_BUKET + "Background/preview/" + path;

            // 更新用户背景图
            String uBackground = userEntity.getBackground();
            userEntity.setBackground(fullPath);

            userDao.updateById(userEntity);

            if (uBackground != null) {
                fileLocalUtils.deleteFile(uBackground);
            }

            return R.ok("背景更新成功");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public R getBackground(Integer userId) {
        UserEntity userEntity = userDao.selectById(userId);
        if(userEntity == null) {
            return R.error(404,"未找到用户");
        }
        String url = userEntity.getBackground();
        return R.ok().put("url",url);
    }


}